﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.XPath;

namespace PDFWriter
{
    public class DocumentRoot : INode
    {
        const string RESOURCE_TAG = "DocumentRoot";
        const string OBJECT_ID = "id";
        public const string GENERATION_ID = "GenID";
        public List<PDFObject> generatedObject = new List<PDFObject>();
        public string ReferenceID
        {
            get;
            set;
        }  
        string xmlString = "<DocumentRoot id=\"5\" MediaBox=\"0,0,612,792\" >" +
      "<Page id=\"1\">" +
        "<Resource id=\"3\" >" +
          "<Dictionary>" +
             "<DictionaryElement type=\"name\" value=\"ProcSet\">[/PDF/Text]</DictionaryElement>" +
             "<DictionaryElement type=\"name\" value=\"Font\">" +
               "<Dictionary>" +
                 "<DictionaryElement type=\"name\" value=\"F1\"><ObjRef>3</ObjRef> </DictionaryElement>" +
               "</Dictionary>" +
             "</DictionaryElement>" +
           "</Dictionary>" +
        "</Resource>" +
        "<Content id=\"2\">" +
            "<Dictionary>" +
              "<DictionaryElement type=\"name\" value=\"length\">51</DictionaryElement>" +
            "</Dictionary>" +
            "<Stream>" +
              "BT\n" +
              "/F1 24 Tf\n" +
              "1 0 0 1 260 600 Tm\n" +
              "(Hello World)Tj\n" +
              "ET\n" +
            "</Stream>" +
          "</Content>" +
      "</Page>" +
    "</DocumentRoot>";

        public const string DOCUMENT_ROOT = "DocumentRoot";
        public const string MEDIA_BOX = "MediaBox";
        XmlDocument reader = new XmlDocument();

        public DocumentRoot(string xmlString)
        {
            this.xmlString = xmlString;
            reader.LoadXml(xmlString);
        }

        public DocumentRoot()
        {
            reader.LoadXml(xmlString);
        }

        public PDFObject GetPDFObject()
        {
            return GenerateNewPDFObject(ProcessXML());
        }

        public List<PDFObject> GetPDFObjects()
        {
            ProcessXML();
            return generatedObject;
        }

        private string ProcessXML()
        {
            StringBuilder builder = new StringBuilder();
            if (reader.FirstChild.Name == DOCUMENT_ROOT)
            {
                builder.Append("<</Type /Pages\n");
                builder.Append("/Kids " + DocumentPage.GetDocumentPageArray(reader.FirstChild.ChildNodes) + "\n");
                builder.Append("/Count " + DocumentPage.GetPageCount(reader.FirstChild.ChildNodes) + "\n");
                builder.Append("/MediaBox " + " [ " + GetMediaBox(reader.FirstChild.Attributes[MEDIA_BOX].Value) + " ] " + "\n");
                builder.Append(" >>");
            }

            

            string generationID = null;           
            if (reader.FirstChild.Name == DOCUMENT_ROOT)
            {
                if (reader.FirstChild.Attributes[OBJECT_ID].Value != null)
                {
                    generationID = reader.FirstChild.Attributes[OBJECT_ID].Value;
                    if (reader.FirstChild.Attributes[GENERATION_ID] != null)
                    {
                        generationID += reader.FirstChild.Attributes[GENERATION_ID].Value;
                    }
                    else
                    {
                        generationID += " 0";
                    }

                }
                ReferenceID = generationID + " R";                
            }
            foreach (XmlNode node in reader.FirstChild.ChildNodes)
            {
                generatedObject.AddRange(Utility.GetPDFObjects(node.OuterXml + DocumentPage.DELIMETER + ReferenceID));
            }

            string fullText = generationID + " obj\n" + builder.ToString() + "\nendobj";

            generatedObject.Add(GenerateNewPDFObject(fullText));
            return fullText;
        }

        private string GetMediaBox(string mediaBox)
        {
            return mediaBox.Replace(',', ' ');
        }
        
        private PDFObject GenerateNewPDFObject(string fullText)
        {
            return new PDFObject() { Text = fullText, ObjectType = DOCUMENT_ROOT, ObjectID = ReferenceID };
        }


    }
}
